#ifndef	__attr_buffer_basis_H__
#define	__attr_buffer_basis_H__

#include "rendPlatform.hpp"

#include <string>

namespace rend
{

enum AttrElementType
{
	ATTR_ELEMENT_INT8,
	ATTR_ELEMENT_UINT8,
	ATTR_ELEMENT_INT16,
	ATTR_ELEMENT_UINT16,
	ATTR_ELEMENT_INT32,
	ATTR_ELEMENT_UINT32,
	ATTR_ELEMENT_INT64,
	ATTR_ELEMENT_UINT64,
	ATTR_ELEMENT_FLOAT16,
	ATTR_ELEMENT_FLOAT32,
	ATTR_ELEMENT_FLOAT64,

	ATTR_ELEMENT_COUNT,
	ATTR_ELEMENT_FORCE_TYPE = (unsigned) -1
};


inline unsigned sizeofAttrElement(const AttrElementType type)
{
	static const unsigned size[ATTR_ELEMENT_COUNT] =
	{
		1,	// ATTR_ELEMENT_INT8
		1,	// ATTR_ELEMENT_UINT8
		2,	// ATTR_ELEMENT_INT16
		2,	// ATTR_ELEMENT_UINT16
		4,	// ATTR_ELEMENT_INT32
		4,	// ATTR_ELEMENT_UINT32
		8,	// ATTR_ELEMENT_INT64
		8,	// ATTR_ELEMENT_UINT64
		2,	// ATTR_ELEMENT_FLOAT16
		4,	// ATTR_ELEMENT_FLOAT32
		8	// ATTR_ELEMENT_FLOAT64
	};

	return size[type];
}


struct AttrDescriptor
{
	std::string		semantics;
	AttrElementType	element_type;
	unsigned		element_count;

	AttrDescriptor()
	{}

	AttrDescriptor(
	   const std::string& sem,
	   const AttrElementType type,
	   const unsigned count)
	: semantics(sem)
	, element_type(type)
	, element_count(count)
	{}

	bool operator ==(const AttrDescriptor& other) const;

	bool operator !=(const AttrDescriptor& other) const;
};


inline bool AttrDescriptor::operator ==(
	const AttrDescriptor& other) const
{
	return
		semantics == other.semantics &&
		element_type == other.element_type &&
		element_count == other.element_count;
}


inline bool AttrDescriptor::operator !=(
	const AttrDescriptor& other) const
{
	return !operator ==(other);
}

} // namespace rend

#endif	// __attr_buffer_basis_H__
